<!---
	Copyright 2010 Edward Trudeau, Jeremy Battle
    This software is freely available under the MIT License: http://www.opensource.org/licenses/mit-license.php
    http://ayc.googlecode.com
    
--->

<cfcomponent name="User" output="false" extends="_User">

   <cfset variables.stSecurity = structNew() />
   <cfset variables.PermissionService = "" />
	
   
   <cffunction name="loadSecurity" output="no" access="public" hint="Loads all object permissions and object type roles for a user">
   		<cfargument name="UserPermService" type="ayc.cfc.object.UserPermService" required="yes" />
        <cfargument name="UserRoleService" type="ayc.cfc.object.UserRoleService" required="yes" />
        <cfargument name="PermissionService" type="ayc.cfc.object.PermissionService" required="yes" />
        <cfargument name="ObjectService" type="ayc.cfc.object.AycObjService" required="yes" />
        <cfargument name="ObjTypeService" type="ayc.cfc.object.ObjTypeService" required="yes" />
        
        <cfset variables.PermissionService = arguments.PermissionService />
        
   		<cfset loadRoles(arguments.UserRoleService, arguments.PermissionService, arguments.ObjTypeService) />
        <cfset loadPerms(arguments.UserPermService, arguments.PermissionService, arguments.ObjectService, arguments.ObjTypeService) />
   </cffunction>
   
   <!--- load all roles first; this will give the permission object for the object type generally.  Then individual object permissions under this role will be listed as keys of the role. Both the object type and object permissions are just permissions objects  --->
   
   <cffunction name="loadRoles" output="no" access="public" hint="Loads all roles (permissions for object types) for the current user." returntype="void">
        <cfargument name="UserRoleService" type="ayc.cfc.object.UserRoleService" required="yes" />
        <cfargument name="PermissionService" type="ayc.cfc.object.PermissionService" required="yes" />
        <cfargument name="ObjTypeService" type="ayc.cfc.object.ObjTypeService" required="yes" />
        
        <cfset var aRoles = "" />
        <cfset var iii = "" />
        <cfset var nextRole = "" />
        <cfset var nextOT = "" />
   		       
        <cfset aRoles = arguments.UserRoleService.getUserRoles(UserID=this.getUserID()) />
        <cfif arrayLen(aRoles)>
        	<cfloop from="1" to="#arrayLen(aRoles)#" index="iii">
            	<cfset nextRole = arguments.PermissionService.getPermission(aRoles[iii].getPermId()) />
                <cfset nextOT = arguments.ObjTypeService.getObjType(aRoles[iii].getObjectTypeId()) />
                <cfif isObject(nextRole)>
                	<cfset variables.stSecurity["#nextOT.getObjectTypeName()#"] = structNew() />
                    <cfset variables.stSecurity["#nextOT.getObjectTypeName()#"]["__aycOTRole"] = nextRole />
                </cfif>
            </cfloop>
        </cfif>
        
        <cfreturn />
   </cffunction>
   
   <!--- now load individual object permissions under each role --->
   
   <cffunction name="loadPerms" output="no" access="public" hint="Loads all permissions on objects for the current user" returntype="void">
   		<cfargument name="UserPermService" type="ayc.cfc.object.UserPermService" required="yes" />
        <cfargument name="PermissionService" type="ayc.cfc.object.PermissionService" required="yes" />
        <cfargument name="ObjectService" type="ayc.cfc.object.AycObjService" required="yes" />
        <cfargument name="ObjTypeService" type="ayc.cfc.object.ObjTypeService" required="yes" />
        
        <cfset var aPerms = "" />
        <cfset var iii = "" />
        <cfset var nextPerm = "" />
        <cfset var nextObj = "" />
        <cfset var nextOT = "" />
                
        <cfset aPerms = arguments.UserPermService.getUserPerms(UserID=this.getUserID()) />

        <cfif arrayLen(aPerms)>
        	<cfloop from="1" to="#arrayLen(aPerms)#" index="iii">
            	<cfset nextPerm = arguments.PermissionService.getPermission(aPerms[iii].getPermId()) />
                <cfset nextObj = arguments.ObjectService.getAycObj(aPerms[iii].getObjectId()) />
                <cfset nextOT = arguments.ObjTypeService.getObjType(nextObj.getObjectTypeId()) />
                <cfif isObject(nextPerm) AND structKeyExists(variables.stSecurity, "#nextOT.getObjectTypeName()#")>
                	<cfset variables.stSecurity["#nextOT.getObjectTypeName()#"]["#nextObj.getObjectName()#"] = nextPerm />
                </cfif>
            </cfloop>
        </cfif>
        
   </cffunction>
   
   <cffunction name="getPerms" output="no" returntype="struct" access="public" hint="Returns the array of permissions objects assigned to this user">
   		<cfreturn variables.stSecurity />
   </cffunction>
   
   <cffunction name="getRoles" output="no" returntype="struct" access="public" hint="Returns the array of roles (permissions on object types) assigned to this user">
   		<cfreturn variables.stSecurity />
   </cffunction>
   
   <cffunction name="hasRole" output="no" returntype="boolean" access="public" hint="True if the user has the requested role on the specified object type">	
   		<cfargument name="objectType" type="string" required="yes" />
        <cfargument name="role" type="string" required="yes" />
        
   		<cfif structKeyExists(variables.stSecurity, arguments.objectType)>
        	<cfreturn variables.PermissionService.checkPerm(arguments.objectType, variables.stSecurity["#arguments.objectType#"]["__aycOTRole"].getPermissionName(), arguments.role) />
        <cfelse>
        	<cfreturn false />
        </cfif>
        
   </cffunction>
   
   <cffunction name="hasPerm" output="no" returntype="boolean" access="public" hint="True if the user has the requested role on the specified object">	
   		<cfargument name="objectType" type="string" required="yes" />
        <cfargument name="objectName" type="string" required="yes" />
        <cfargument name="role" type="string" required="yes" />
        
   		<cfif NOT structKeyExists(variables.stSecurity, arguments.objectType)>
        	<cfreturn false />
        <cfelseif NOT structKeyExists(variables.stSecurity["#arguments.objectType#"], arguments.objectName)>
        	<cfreturn false />
        <cfelse>
        	<cfreturn variables.PermissionService.checkPerm(arguments.objectType, variables.stSecurity["#arguments.objectType#"]["#arguments.objectName#"].getPermissionName(), arguments.role) />
        </cfif>
        
   </cffunction>
   
</cfcomponent>


